jetcrab\parser\statements/
variable.rs1use crate::ast::{Node, VariableDeclaration, VariableDeclarator};
2use crate::lexer::TokenKind;
3use crate::parser::error::ParseResult;
4use crate::parser::Parser;
5
6impl Parser {
7 pub fn parse_variable_declaration(&mut self) -> ParseResult<Node> {
8 let kind = if let Some(token) = &self.current {
9 if let TokenKind::Keyword(kw) = &token.kind {
10 match kw.as_str() {
11 "let" => "let",
12 "const" => "const",
13 "var" => "var",
14 _ => unreachable!(),
15 }
16 } else {
17 unreachable!()
18 }
19 } else {
20 unreachable!()
21 };
22
23 self.advance();
24
25 let mut declarations = Vec::new();
26
27 loop {
28 let id = if self.check(TokenKind::LeftBrace) || self.check(TokenKind::LeftBracket) {
29 self.parse_destructuring_pattern()?
30 } else {
31 self.parse_identifier()?
32 };
33 let init = if self.check(TokenKind::Assign) {
34 self.advance();
35 Some(Box::new(self.parse_expression()?))
36 } else {
37 None
38 };
39
40 let span = self.create_span_from_tokens();
41 declarations.push(VariableDeclarator {
42 id: Box::new(id),
43 init,
44 span: Some(span),
45 });
46
47 if !self.check(TokenKind::Comma) {
48 break;
49 }
50 self.advance();
51 }
52
53 if self.check(TokenKind::Semicolon) {
54 self.advance();
55 }
56
57 let span = self.create_span_from_tokens();
58 Ok(Node::VariableDeclaration(VariableDeclaration {
59 kind: kind.to_string(),
60 declarations,
61 span: Some(span),
62 }))
63 }
64
65 pub fn parse_variable_declaration_without_semicolon(&mut self) -> ParseResult<Node> {
66 let kind = if let Some(token) = &self.current {
67 if let TokenKind::Keyword(kw) = &token.kind {
68 match kw.as_str() {
69 "let" => "let",
70 "const" => "const",
71 "var" => "var",
72 _ => unreachable!(),
73 }
74 } else {
75 unreachable!()
76 }
77 } else {
78 unreachable!()
79 };
80
81 self.advance();
82
83 let mut declarations = Vec::new();
84
85 loop {
86 let id = if self.check(TokenKind::LeftBrace) || self.check(TokenKind::LeftBracket) {
87 self.parse_destructuring_pattern()?
88 } else {
89 self.parse_identifier()?
90 };
91 let init = if self.check(TokenKind::Assign) {
92 self.advance();
93 Some(Box::new(self.parse_expression()?))
94 } else {
95 None
96 };
97
98 let span = self.create_span_from_tokens();
99 declarations.push(VariableDeclarator {
100 id: Box::new(id),
101 init,
102 span: Some(span),
103 });
104
105 if !self.check(TokenKind::Comma) {
106 break;
107 }
108 self.advance();
109 }
110
111 let span = self.create_span_from_tokens();
112 Ok(Node::VariableDeclaration(VariableDeclaration {
113 kind: kind.to_string(),
114 declarations,
115 span: Some(span),
116 }))
117 }
118}